#include <stdio.h>

/************************************************** 
A..>C-->B-->E
     \->D-/

***************************************************/


class A
{
public:
    A() { printf("Calling %s, this:%p\n", "A::A()", this); }
    virtual void vf() { printf("Calling %s, this:%p\n", "A::vf()", this); }
    ~A() { printf("Calling %s\n", "A::~A()"); }
    int a;
};


class C : virtual public A
{
    
public:
    C() { printf("Calling %s, this:%p\n", "C::C()", this); }
    virtual void vf() override { printf("Calling %s, this:%p\n", "C::vf()", this); }
    ~C() { printf("Calling %s\n", "C::~C()"); }
    int c;
};

class B : public C
{
public:
    B() { printf("Calling %s, this:%p\n", "B::B()", this); }
    virtual void vf() override { printf("Calling %s, this:%p\n", "B::vf()", this); }
    ~B() { printf("Calling %s\n", "B::~B()"); }
    int b;
};

class D : public C
{
public:
    D() { printf("Calling %s, this:%p\n", "D::D()", this); }
    virtual void vf() override { printf("Calling %s, this:%p\n", "D::vf()", this); }
    ~D() { printf("Calling %s\n", "D::~D()"); }
    int d;
};

class E : public B, public D
{
public:
    E() { printf("Calling %s, this:%p\n", "E::E()", this); }
    virtual void vf() override { printf("Calling %s, this:%p\n", "E::vf()", this); }
    ~E() { printf("Calling %s\n", "E::~E()"); }
    int e;

};

int main(void)
{
    E e;
    printf("&e:%p\n", &e);
    auto & a = dynamic_cast<A&>(e);
    printf("&a:%p\n", &a);
    a.vf();
    // auto c = dynamic_cast<C&>(e); #compile error: ‘C’ is an ambiguous base of ‘E’
    auto & d = dynamic_cast<D&>(e);
    printf("&d:%p\n", &d);
    auto & c = dynamic_cast<C&>(d);
    printf("&c:%p\n", &c);
    c.vf();
    //auto c2 = dynamic_cast<C&>(a); #runtime error:  std::bad_cast
    
    return 0;   
}
